package com.zhengjiang.api.demo.interceptors;

import com.zhengjiang.api.demo.annotation.NotRepeatSubmit;
import com.zhengjiang.api.demo.model.TokenInfo;
import com.zhengjiang.api.demo.utils.ApiUtil;
import com.zhengjiang.api.demo.utils.MD5Util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.concurrent.TimeUnit;

@Component
public class TokenInterceptor extends HandlerInterceptorAdapter {

    @Autowired
    RedisTemplate redisTemplate;

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

        String token = request.getHeader("token");
        String timestamp = request.getHeader("timestamp");
        String sign = request.getHeader("sign");
        String nonce = request.getHeader("nonce");

        Assert.isTrue(!StringUtils.isEmpty(token) && !StringUtils.isEmpty(timestamp) && !StringUtils.isEmpty(sign),"缺少参数");
        NotRepeatSubmit notRepeatSubmit = ApiUtil.getNotRepeatSubmit(handler);
        long expireTime = notRepeatSubmit==null ? 5 * 60 * 1000:notRepeatSubmit.value();

        long intervalTime = System.currentTimeMillis() - Long.valueOf(timestamp);
        Assert.isTrue(intervalTime<expireTime,"请求超时，请重新请求");

        TokenInfo tokenInfo = (TokenInfo) redisTemplate.opsForValue().get(token);
        Assert.notNull(tokenInfo,"token错误");

        String signString =  ApiUtil.concatSignString(request) + tokenInfo.getAppInfo().getKey() + token + timestamp + nonce;
        String signature = MD5Util.encode(signString);
        Assert.isTrue(sign.equals(signature),"签名错误");

        //标准注解的接口 校验重复提交
        if(notRepeatSubmit!=null){
            boolean hasKey = redisTemplate.hasKey(signature);
            Assert.isTrue(!hasKey,"请勿重复提交");
            redisTemplate.opsForValue().set(signature,0,expireTime, TimeUnit.SECONDS);
        }


        return super.preHandle(request, response, handler);
    }
}
